"""
导出导入模块路由
"""
from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi.responses import FileResponse, JSONResponse
from sqlalchemy.orm import Session
from pathlib import Path
from datetime import datetime
import json

from ..db import get_db
from ..schemas import ParameterDict, MessageResponse
from ..db.parameters.crud import (
    get_project_by_name_en, get_project_parameters_dict,
    get_parameter_categories, get_parameters_with_values
)
# 旧版本导入导出已迁移到 io_v2，不再使用 io_formats.registry
from ..io_v2 import IOFormat, ProjectExporter, ProjectImporter
from ..io_v2.services.exporter import UnknownExportFormatError
from ..io_v2.services.importer import UnknownImportFormatError

router = APIRouter(prefix="/api", tags=["导出导入"])


@router.get("/projects/{project_name_en}/parameters", response_model=ParameterDict)
async def get_project_parameters_endpoint(project_name_en: str, db: Session = Depends(get_db)):
    """获取项目的完整参数字典（用于API调用）"""
    # 检查项目是否存在
    project = get_project_by_name_en(db, project_name_en)
    if not project:
        raise HTTPException(
            status_code=404,
            detail=f"项目 '{project_name_en}' 不存在"
        )
    
    parameters_dict = get_project_parameters_dict(db, project_name_en)
    
    # 添加元数据
    metadata = {
        "project_name": project.name,
        "project_name_en": project.name_en,
        "time_horizon": project.time_horizon,
        "start_year": project.start_year,
        "year_step": project.year_step,
        "end_year": project.end_year,
        "export_time": datetime.utcnow().isoformat(),
        "data_types": {}
    }
    
    # 添加数据类型信息
    for category_name, category_data in parameters_dict.items():
        metadata["data_types"][category_name] = {}
        for param_name, param_value in category_data.items():
            if isinstance(param_value, list):
                if param_value and isinstance(param_value[0], (int, float)):
                    metadata["data_types"][category_name][param_name] = {
                        "type": "list",
                        "element_type": "number" if isinstance(param_value[0], float) else "integer"
                    }
                else:
                    metadata["data_types"][category_name][param_name] = {
                        "type": "list",
                        "element_type": "string"
                    }
            elif isinstance(param_value, (int, float)):
                metadata["data_types"][category_name][param_name] = {
                    "type": "number" if isinstance(param_value, float) else "integer"
                }
            elif isinstance(param_value, bool):
                metadata["data_types"][category_name][param_name] = {
                    "type": "boolean"
                }
            else:
                metadata["data_types"][category_name][param_name] = {
                    "type": "string"
                }
    
    return ParameterDict(data=parameters_dict, metadata=metadata)


@router.get("/export/formats")
async def get_export_formats():
    """获取支持的导出格式列表（使用新版本策略）"""
    from ..io_v2.services.exporter import EXPORT_STRATEGIES
    
    formats = []
    for format_enum, strategy_cls in EXPORT_STRATEGIES.items():
        # 从策略类获取格式信息
        format_info = strategy_cls.get_format_info()
        formats.append(format_info)
    
    return {"formats": formats}


@router.get("/import/formats")
async def get_import_formats():
    """获取支持的导入格式列表（使用新版本策略）"""
    from ..io_v2.services.importer import IMPORT_STRATEGIES
    
    formats = []
    for format_enum, strategy_cls in IMPORT_STRATEGIES.items():
        # 从策略类获取格式信息
        format_info = strategy_cls.get_format_info()
        formats.append(format_info)
    
    return {"formats": formats}


@router.post("/projects/{project_name_en}/export/{format_type}")
async def export_project_parameters(
    project_name_en: str,
    format_type: str,
    db: Session = Depends(get_db),
):
    """导出项目参数（使用新版本策略）"""
    try:
        format_enum = IOFormat(format_type)
    except ValueError:
        raise HTTPException(status_code=400, detail=f"不支持的导出格式: {format_type}")

    exporter = ProjectExporter(db)
    try:
        export_response = exporter.export(project_name_en, format_enum)
    except ProjectExporter.ProjectNotFoundError as exc:
        raise HTTPException(status_code=404, detail=str(exc))
    except UnknownExportFormatError as exc:
        raise HTTPException(status_code=400, detail=str(exc))
    except Exception as exc:  # noqa: BLE001
        raise HTTPException(status_code=500, detail=f"导出失败: {exc}")

    file_path = export_response.result.file_path
    if not file_path.exists():
        raise HTTPException(status_code=500, detail="导出文件生成失败")

    # 如果是 JSON 格式，直接返回 JSON 数据而不是文件下载
    if format_enum == IOFormat.JSON:
        with file_path.open("r", encoding="utf-8") as f:
            json_data = json.load(f)
        return JSONResponse(content=json_data)

    return FileResponse(
        path=str(file_path),
        filename=file_path.name,
        media_type=export_response.result.mime_type or "application/octet-stream",
        headers={"Content-Disposition": f"attachment; filename={file_path.name}"},
    )


@router.post("/import/upload/{format_type}", response_model=MessageResponse)
async def import_by_upload(
    format_type: str,
    request: Request,
    db: Session = Depends(get_db),
):
    """上传文件导入（使用新版本策略）"""
    raw = await request.body()
    filename = request.headers.get("X-Filename")
    if not raw or not filename:
        raise HTTPException(status_code=400, detail="未提供文件或文件名")

    try:
        format_enum = IOFormat(format_type)
    except ValueError:
        raise HTTPException(status_code=400, detail=f"不支持的导入格式: {format_type}")

    # 从策略类获取支持的扩展名
    from ..io_v2.services.importer import IMPORT_STRATEGIES
    
    strategy_cls = IMPORT_STRATEGIES.get(format_enum)
    if not strategy_cls:
        raise HTTPException(status_code=400, detail=f"不支持的导入格式: {format_type}")
    
    format_info = strategy_cls.get_format_info()
    allowed_extensions = format_info.get("extensions", [])
    
    import os
    _, ext = os.path.splitext(filename)
    if allowed_extensions and ext.lower() not in [e.lower() for e in allowed_extensions]:
        raise HTTPException(
            status_code=400,
            detail=f"文件类型不被支持或后缀不正确，支持的扩展名: {', '.join(allowed_extensions)}"
        )

    import tempfile

    tmp_dir = tempfile.mkdtemp()
    save_path = os.path.join(tmp_dir, filename)
    with open(save_path, "wb") as f:
        f.write(raw)

    importer = ProjectImporter(db)
    try:
        response = importer.import_file(Path(save_path), format_enum)
    except UnknownImportFormatError as exc:
        raise HTTPException(status_code=400, detail=str(exc))
    except Exception as exc:  # noqa: BLE001
        raise HTTPException(status_code=400, detail=f"导入失败：{exc}")

    return MessageResponse(
        message=(
            f"导入完成：{response.project_name} ({response.project_name_en}) "
            f"- 分类 {response.categories} 个，参数 {response.parameters} 个，值 {response.values} 个"
        )
    )


